#include <fermat/common/token.h>
#include <fermat/common/string.h>
#include <fermat/common/ascii.h>


namespace fermat {


Token::Token(bool isIgnore) : _ignored(isIgnore)
{
}


Token::~Token()
{
}


bool Token::start(char c, std::istream& istr)
{
	_value = c;
	return false;
}


bool Token::finish(std::istream& istr)
{
	return true;
}


Token::TType Token::tokenClass() const
{
	return INVALID_TOKEN;
}

		
std::string Token::asString() const
{
	return _value;
}


int64_t Token::asInteger64() const
{
	return string_to_int(_value);
}


uint64_t Token::asUnsignedInteger64() const
{
	 int64_t ret = string_to_int(_value);
	 return static_cast<uint64_t>(ret);
}


int Token::asInteger() const
{
	 int64_t ret = string_to_int(_value);
	 return static_cast<int>(ret);
}


unsigned Token::asUnsignedInteger() const
{
	int64_t ret = string_to_int(_value);
	 return static_cast<unsigned>(ret);
}


double Token::asFloat() const
{
	double ret;
	from_str(_value, ret);
	return ret;
}


char Token::asChar() const
{
	return _value.empty() ? 0 : _value[0];
}


void Token::ignore(bool isIgnored)
{
	_ignored = isIgnored;
}

bool Token::ignored() const
{
	return _ignored;
}


InvalidToken::InvalidToken()
{
}


InvalidToken::~InvalidToken()
{
}


Token::TType InvalidToken::tokenClass() const
{
	return INVALID_TOKEN;
}


EOFToken::EOFToken()
{
}


EOFToken::~EOFToken()
{
}


Token::TType EOFToken::tokenClass() const
{
	return EOF_TOKEN;
}


WhitespaceToken::WhitespaceToken() : Token(true)
{
}


WhitespaceToken::~WhitespaceToken()
{
}


Token::TType WhitespaceToken::tokenClass() const
{
	return WHITESPACE_TOKEN;
}


bool WhitespaceToken::start(char c, std::istream& istr)
{
	if (Ascii::isSpace(c)) {
		_value = c;
		return true;
	}
	return false;
};


bool WhitespaceToken::finish(std::istream& istr)
{
	int c = istr.peek();
	while (Ascii::isSpace(c)) {
		istr.get();
		_value += (char) c;
		c = istr.peek();
	}
	return true;
}


} 